package com.fan.gofast.compent;

import com.fan.gofast.util.AgentUtil;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * @ClassName ExecutorConfig
 * @Decription
 * @Author wangjing
 * @Date 2019/8/20 16:18
 **/
@Slf4j
@Configuration
public class DefaultExecutorConfiguration {

    @Bean(value = "taskExecutor", destroyMethod = "shutdown")
    @ConditionalOnExpression("#{'true'.equals(environment['spring.threadpool.enabled'])}")
    public ThreadPoolExecutor taskExecutor(Environment environment) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2 * Runtime.getRuntime().availableProcessors(),
                4 * Runtime.getRuntime().availableProcessors(), 3000, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000));
        executor.setThreadFactory(new ThreadFactoryBuilder().setNameFormat("myb-pool-%d").setUncaughtExceptionHandler((thread, throwable) -> {

        }).build());
        // 设置拒绝策略
        executor.setRejectedExecutionHandler((r, ex) -> {
            String content;
            if (!ex.isShutdown()) {
                r.run();
                content = "当前任务由" + Thread.currentThread().getName() + "执行,线程池队列已满,请留意！";
            } else {
                content = "线程池关闭，当前任务被抛弃,请留意！";
            }
            String applicationName = "";
            try {
                 applicationName = environment.getProperty("spring.application.name", "");
                if(StringUtils.isEmpty(applicationName)){
                    applicationName = environment.getProperty("spring.application.name");
                }
                applicationName = applicationName+"-" + environment.getActiveProfiles()[0];
                content = content + " 工程：" + applicationName
                        + " IP:" + AgentUtil.getServerIp() + " hostname:" + InetAddress.getByName(AgentUtil.getServerIp()).getHostName() +
                        "<br> " + r.toString();
            } catch (UnknownHostException e) {
            }
            content = content + "<br>" + String.format("%s, taskCount [%s], completedTaskCount [%s], activeCount [%s], queueSize [%s]",
                    "线程池情况",
                    ex.getTaskCount(),
                    ex.getCompletedTaskCount(),
                    ex.getActiveCount(),
                    ex.getQueue().size());
            log.info("{}, taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
                    "线程池情况",
                    ex.getTaskCount(),
                    ex.getCompletedTaskCount(),
                    ex.getActiveCount(),
                    ex.getQueue().size());

        });

        log.info("init taskExecutor.");

        return executor;
    }

    @ConditionalOnExpression("#{'true'.equals(environment['spring.scheduled.enabled'])}")
    @Bean(value = "scheduledThreadPoolExecutor", destroyMethod = "shutdown")
    public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor() {
        return new ScheduledThreadPoolExecutor(4);
    }

}
